package com.ocm.core.associationType.service.impl;

import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Session;
import javax.jcr.Value;

import com.ocm.core.constant.OCMConstant;
import com.ocm.core.domain.ClassDefinition;
import com.ocm.core.domain.PropertyDefinition;
import com.ocm.core.domain.PropertyType;
import com.ocm.core.exception.OCMException;
import com.ocm.core.model.ClassInstance;
import com.ocm.core.model.ReferenceValue;
import com.ocm.core.model.ReferenceValue.ITEM_STATUS;
import com.ocm.core.service.AssociationTypeService;
import com.ocm.core.service.JCRService;

public class OneToOneServiceImpl implements AssociationTypeService {

   private JCRService jcrService;

   public Object getPropertyValue(Property property) throws OCMException {
      try{
         Value value = property.getValue();
         Object result = value == null ? "" : value.getString();
         return result;
      }catch (Exception exception){
         throw new OCMException(exception);
      }
   }

   public void processReferenceValue(Node instanceClass, String propertyName, ReferenceValue referenceValue) throws OCMException {
      try{
         Value value = null;
         if (referenceValue.getItemStatus(0) == ITEM_STATUS.REMOVE)
            value = null;
         else
            value = PropertyType.OBJECT.convertValue(jcrService.getNodeId(instanceClass.getSession(), referenceValue.getUUID(0)));
         instanceClass.setProperty(propertyName, value);
      }catch (Exception exception){
         throw new OCMException(exception);
      }
   }

   public void setJCRService(JCRService jcrService) {
      this.jcrService = jcrService;
   }

   public Object getPropertyObject(Property property) throws OCMException {
      try{
         Object result = property.getNode();
         return result;
      }catch (Exception exception){
         throw new OCMException(exception);
      }
   }

   public Object processClassInstance(Session session, Object propertyValue, long classDef, List<PropertyDefinition> filterProperties, int maxItems)
         throws OCMException {
      try{
         ClassInstance classInstance = null;
         if (propertyValue != null) {
            classInstance = new ClassInstance();
            Node currentNode = (Node) propertyValue;
            Map<PropertyDefinition, Object> propertyValues = this.jcrService.getValues(currentNode,
                  filterProperties);
            ClassDefinition classDefinition = new ClassDefinition();
            classDefinition.setId(classDef);
            classInstance.setClassDefinition(classDefinition);
            classInstance.setProperties(propertyValues);
            classInstance.setNodeUUID(currentNode.getIdentifier());
            classInstance.setNodeName(currentNode.getName());
            classInstance.setRealPath(currentNode.getPath());
         }
         return classInstance;
      }catch (Exception exception){
         throw new OCMException(exception);
      }
   }

   public boolean support(Property property) throws OCMException {
      try{
         if (property.isMultiple()==false && (property.getNode() != null) && !(OCMConstant.SYSTEM_RELATED_PROPERTY.equalsIgnoreCase(property.getName())))
            return true; 
         return false;
      }catch (Exception exception){
         throw new OCMException(exception);
      }
   }

   public void removeReference(Property property, Node removeNode) throws OCMException {
      try{
         property.remove();
      }catch (Exception exception){
         throw new OCMException(exception);
      }
   }
}
